﻿using DatabaseTransfer.Interfaces;
using DatabaseTransfer.Logs;
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseTransfer.Tables
{
    [Serializable()]
    public class Table :ISerializable
    {
        private static ILog logger = LogFactory.GetLogger(typeof(Table));

        [ColumnInfoAttribute("TABLE_CATALOG", typeof(String))]
        public string TableCatalog { get; set; }

        [ColumnInfoAttribute("TABLE_NAME", typeof(String))]
        public string TableName { get; set; }

        [ColumnInfoAttribute("TABLE_SCHEMA", typeof(String))]
        public string TableSchema { get; set; }

        [ColumnInfoAttribute("TABLE_TYPE", typeof(String))]
        public string TableType { get; set; }

        [ColumnInfoAttribute("ENGINE", typeof(String))]
        public string Engine { get; set; }

        [ColumnInfoAttribute("VERSION", typeof(String))]
        public string Version { get; set; }

        [ColumnInfoAttribute("ROW_FORMAT", typeof(String))]
        public string RowFormat { get; set; }

        [ColumnInfoAttribute("TABLE_COLLATION", typeof(String))]
        public string TableCollation { get; set; }

        [ColumnInfoAttribute("CHECKSUM", typeof(String))]
        public string Checksum { get; set; }

        [ColumnInfoAttribute("CREATE_OPTIONS", typeof(String))]
        public string CreateOptions { get; set; }

        [ColumnInfoAttribute("TABLE_COMMENT", typeof(String))]
        public string TableComment { get; set; }

        [ColumnInfoAttribute("TABLE_ROWS", typeof(int))]
        public int TableRows { get; set; }

        [ColumnInfoAttribute("AVG_ROW_LENGTH", typeof(int))]
        public int AvgRowLength { get; set; }

        [ColumnInfoAttribute("DATA_LENGTH", typeof(int))]
        public int DataLength { get; set; }

        [ColumnInfoAttribute("MAX_DATA_LENGTH", typeof(int))]
        public int MaxDataLength { get; set; }

        [ColumnInfoAttribute("INDEX_LENGTH", typeof(int))]
        public int IndexLength { get; set; }

        [ColumnInfoAttribute("DATA_FREE", typeof(int))]
        public int DataFree { get; set; }

        [ColumnInfoAttribute("AUTO_INCREMENT", typeof(int))]
        public int AutoIncrement { get; set; }

        [ColumnInfoAttribute("CREATE_TIME", typeof(DateTime))]
        public DateTime CreateTime { get; set; }

        [ColumnInfoAttribute("UPDATE_TIME", typeof(DateTime))]
        public DateTime UpdateTime { get; set; }

        [ColumnInfoAttribute("CHECK_TIME", typeof(DateTime))]
        public DateTime CheckTime { get; set; }

        public List<TableColumn> TableColumns { get; set; }

        public AbstractDatabase Database { get; set; }

        public Table() { }

        public Table(SerializationInfo info, StreamingContext ctxt)
        {
            foreach (PropertyInfo fieldInfo in this.GetType().GetProperties())
            {
                try
                {
                    ColumnInfoAttribute columnAttr = (ColumnInfoAttribute)fieldInfo.GetCustomAttribute(typeof(ColumnInfoAttribute));

                    if (columnAttr.Type == typeof(String))
                    {
                        fieldInfo.SetValue(this, (String)info.GetValue(columnAttr.ColumnName, columnAttr.Type));
                    }
                    else if (columnAttr.Type == typeof(int))
                    {
                        fieldInfo.SetValue(this, (int)info.GetValue(columnAttr.ColumnName, columnAttr.Type));
                    }
                    else if (columnAttr.Type == typeof(DateTime))
                    {
                        fieldInfo.SetValue(this, (DateTime)info.GetValue(columnAttr.ColumnName, columnAttr.Type));
                    }
                }
                catch (Exception)
                {
                    continue;
                }
            }
        }


        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            foreach (PropertyInfo fieldInfo in this.GetType().GetProperties())
            {
                try
                {
                    ColumnInfoAttribute columnAttr = (ColumnInfoAttribute)fieldInfo.GetCustomAttribute(typeof(ColumnInfoAttribute));
                    info.AddValue(columnAttr.ColumnName, fieldInfo.GetValue(this));
                }
                catch (Exception)
                {
                    continue;
                }
            }
        }
    }
}
